import fs from 'fs';
import path from 'path';
import store from './store';
import { sendRendererEnv } from './env';
import { winEventHooks } from './events';
import { IpcRendererEventEnum } from '../common/enum';
import { serveProcessControl } from './renderer/serve';
import Electron, { app, Menu, Tray, BrowserWindow, globalShortcut } from 'electron';

const isProd = store.state.isProd;
const isWindows = store.state.isWindows;

/**
 * 创建或切换窗口
 */
export function switchWindow(name: string): BrowserWindow {
    let win: BrowserWindow;
    const windowState = store.getWindowState(name);

    let { url, bounds, maximize } = getWindowBaseConfig(name);

    if (windowState) {
        win = windowState.instance;

        // ...
    } else {
        win = new BrowserWindow({
            show: true,
            center: true,
            icon: store.state.logoPath,
            webPreferences: {
                nodeIntegration: true,
                contextIsolation: false,
                preload: path.join(store.state.runtime.paths.assetsScript, 'renderer-preload.js'),
            },
        });
        store.setWindowState(name, { instance: win });

        win.on('ready-to-show', () => {
            winEventHooks(win);
            sendRendererEnv(win);
        });

        win.on('focus', () => {
            store.setLastActiveWindow(win);
            store.setCurrentActiveWindow(win);

            // FIX - Mac 平台下无法使用复制黏贴全选的快捷操作
            if (!isWindows) {
                const contents = win.webContents;
                globalShortcut.register('Command+C', () => {
                    contents.copy();
                });
                globalShortcut.register('Command+V', () => {
                    contents.paste();
                });
                globalShortcut.register('Command+X', () => {
                    contents.cut();
                });
                globalShortcut.register('Command+A', () => {
                    contents.selectAll();
                });
            }
        });

        win.on('blur', () => {
            store.setCurrentActiveWindow(null);

            globalShortcut.unregister('Command+C');
            globalShortcut.unregister('Command+V');
            globalShortcut.unregister('Command+X');
            globalShortcut.unregister('Command+A');
        });

        // 拦截关闭，退至后台
        win.on('close', e => {
            if (store.state.forceQuitWindow) return undefined;
            e.preventDefault();
            win?.hide();
            return false;
        });

        // 页面加载
        if (isProd || url) {
            loadIndex(win, name, url);
        } else {
            win.loadURL(`file://${store.state.runtime.paths.page404}`);
            // 开发模式下页面可能没有构建完成，需要自动刷新加载页面
            let times = 0;
            const timer = setInterval(() => {
                if (times > 5) {
                    clearInterval(timer);
                } else {
                    times++;
                    url = getWindowBaseConfig(name).url;
                    if (url) {
                        loadIndex(win, name, url);
                        clearInterval(timer);
                    }
                }
            }, 4000);
        }
    }

    win.setBounds(bounds);
    if (bounds.x || bounds.y) {
        // ...
    } else {
        win.center();
    }
    maximize && win.maximize();
    win.show();
    win.webContents.send(IpcRendererEventEnum.SHOW_WINDOWS);

    return win;
}

/**
 * 获取窗口基本配置
 */
function getWindowBaseConfig(name: string) {
    let url = '';
    let maximize = false;
    let bounds: Partial<Electron.Rectangle> = {};

    switch (name) {
        case 'nota':
            url = resourcesPath('nota');
            bounds = { width: 1200, height: 750 };
            break;

        case 'copid':
            url = resourcesPath('copid');
            bounds = { width: 270, height: 400 };
            break;

        case 'serve':
            url = resourcesPath('serve');
            bounds = { width: 750, height: 650 };
            break;

        case 'filow':
            maximize = true;
            url = resourcesPath('filow');
            bounds = { width: 1200, height: 750 };
            break;
    }

    return { url, bounds, maximize };
}

/**
 * 设置系统托盘
 */
export function createTray(): void {
    const menuItemTemplate: Electron.MenuItemConstructorOptions[] = [
        {
            label: 'Filow',
            type: 'normal',
            click: () => {
                switchWindow('filow');
            },
        },
        {
            label: 'Serve',
            type: 'normal',
            click: () => {
                switchWindow('serve');
            },
        },
        {
            type: 'separator',
        },
        {
            label: '开发者模式',
            type: 'normal',
            click: () => {
                store.state.lastActiveWindow?.webContents.openDevTools();
            },
        },
        {
            type: 'separator',
        },
        {
            label: '退出',
            type: 'normal',
            click: () => {
                // 防止 close 事件拦截关闭
                store.state.forceQuitWindow = true;
                app.quit();
            },
        },
    ];

    const contextMenu = Menu.buildFromTemplate(
        isWindows
            ? menuItemTemplate
            : [
                  {
                      type: 'submenu',
                      label: 'Teletool',
                      submenu: menuItemTemplate,
                  },
              ],
    );

    if (isWindows) {
        const tray = new Tray(store.state.trayIconPath);
        tray.on('click', () => {
            store.state.lastActiveWindow?.center();
            store.state.lastActiveWindow?.show();
        });
        tray.setContextMenu(contextMenu);
    } else {
        // FIX - 菜单栏按钮莫名其妙自动禁用了
        Menu.setApplicationMenu(contextMenu);
        setInterval(() => {
            Menu.setApplicationMenu(contextMenu);
        }, 10000);
    }
}

/**
 * 页面加载
 */
function loadIndex(win: BrowserWindow, name: string, url: string) {
    win.loadURL(url)
        .then(() => {
            if (name === 'serve') {
                serveProcessControl(win);
            }
        })
        .catch(e => {
            console.error(e);
        });
}

/**
 * 窗口资源访问
 */
function resourcesPath(...dir: string[]) {
    const indexPath = path.join(store.state.runtime.paths.renderer, ...dir, 'index.html');
    if (fs.existsSync(indexPath)) {
        return `file://${indexPath}`;
    } else {
        return '';
    }
}
